package HTTP

import (
	"SQL/db"
	"fmt"
	"logs"
	"net/http"
)

/*
URL: /addUser
/addUser?nickname=newUser&isManager=true&icon=icon1&password=123456&customInfo={"sex":"male"}
{
	"Code":200,
	"Message":"",
	"Result":10008
}*/
type result struct {
	UserID string
}

func addUser(w http.ResponseWriter, req *http.Request) {
	code := Success
	msg := ""
	var obj interface{}
	err := req.ParseForm()
	if err != nil {
		logs.Print("req.ParseForm error", err.Error())
		code = errParseForm
		msg = err.Error()
		writeResult(w, code, msg, obj)
	}

	defer func() {
		writeResult(w, code, msg, obj)
	}()

	password := req.FormValue("password")
	if len(password) == 0 {
		msg = mInvalidEmptyArgs
		code = errInvalidEmptyArgs
		return
	}
	msg, code = checkerr("password", password)
	if code != Success {
		return
	}

	isManager := req.FormValue("isManager")
	if isManager != "true" && isManager != "false" {
		msg = mInvalidBoolArg
		code = errInvalidBoolArg
		return
	}

	nickname := req.FormValue("nickname")
	if len(nickname) == 0 {
		msg = mInvalidNickname
		code = errInvalidNickname
		return
	}

	icon := req.FormValue("icon")
	if len(icon) == 0 {
		icon = "icon1"
	}

	customInfo := req.FormValue("customInfo")
	var custom interface{}
	if len(customInfo) == 0 {
		custom = nil
	} else {
		msg, code = checkerr("customInfo", customInfo)
		if code != Success {
			return
		}
		custom = customInfo
	}
	code, msg, obj = addUserToDB(password, nickname, isManager, icon, custom)
}

func addUserToDB(password string, nickname string, isManager string, icon string, custom interface{}) (code int, msg string, Result interface{}) {
	//插入objects ->返回 id ->插入users ->完成
	DB, err := db.Getdb()
	if err != nil {
		code = errOpenDB
		msg = err.Error()
		return
	}

	tx, err := DB.Begin()
	if err != nil {
		code = errBeginTx
		msg = err.Error()
		return
	}

	defer func() {
		if code != Success {
			err := tx.Rollback()
			if err != nil {
				code = errEndTx
				msg = err.Error()
			}
		}
	}()

	var sql string
	var args []interface{}
	if custom != nil {
		sql = "insert into objects(nickname,icon,isUser,custom) values($1,$2,true,$3) returning id"
		args = append(args, nickname, icon, custom)
	} else {
		sql = "insert into objects(nickname,icon,isUser) values($1,$2,true) returning id"
		args = append(args, nickname, icon)
	}

	stmt, rows, err := db.TxQuery(tx, sql, args...)
	defer stmt.Close()
	if err != nil {
		code = errDBQueryFailed
		msg = err.Error()
		fmt.Println("4", err.Error())
		return
	}

	var userID string
	if !rows.Next() {
		code = errDBQueryFailed
		msg = "no rows"
		return
	}
	err = rows.Scan(&userID)
	defer rows.Close()

	if err != nil {
		code = errRowsScan
		msg = err.Error()
		return
	}
	rows.Close()
	sql = "insert into users(id,password,isManager) values($1,$2,$3)"
	var objs []interface{}
	objs = append(objs, userID, password, isManager)
	err = db.TxExec(tx, sql, objs...)
	if err != nil {
		code = errDBExecFailed
		msg = err.Error()
		return
	}
	err = tx.Commit()
	if err != nil {
		code = errEndTx
		msg = err.Error()
		return
	}
	res := &result{UserID: userID}
	return Success, "", res
}
